home *** CD-ROM | disk | FTP | other *** search
/ Dr. Windows 3 / dr win3.zip / dr win3 / PROGRAMR / OLE2BOOK.ZIP / CHAP13.ZIP / PATRON / IOLECONT.CPP < prev    next >
C/C++ Source or Header  |  1993-07-19  |  11KB  |  420 lines

  1. /*
  2.  * IOLECONT.CPP
  3.  *
  4.  * Implementation of the IOleItemContainer interface for Patron's CPage
  5.  * and CPatronDoc alike, using the constructor parameter fDoc to differentiate.
  6.  *
  7.  * Copyright (c)1993 Microsoft Corporation, All Rights Reserved
  8.  *
  9.  * Kraig Brockschmidt, Software Design Engineer
  10.  * Microsoft Systems Developer Relations
  11.  *
  12.  * Internet  :  kraigb@microsoft.com
  13.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  14.  */
  15.  
  16.  
  17. #include <stdlib.h>
  18. #include "patron.h"
  19.  
  20.  
  21. /*
  22.  * CImpIOleItemContainer::CImpIOleItemContainer
  23.  * CImpIOleItemContainer::~CImpIOleItemContainer
  24.  *
  25.  * Parameters (Constructor):
  26.  *  pObj            LPVOID of the page or pages.
  27.  *  punkOuter       LPUNKNOWN to which we delegate.
  28.  *  fDoc            BOOL indicating if we're in CPatronDoc or CPage
  29.  */
  30.  
  31. CImpIOleItemContainer::CImpIOleItemContainer(LPVOID pObj
  32.     , LPUNKNOWN punkOuter, BOOL fDoc)
  33.     {
  34.     m_cRef=0;
  35.     m_fDoc=fDoc;
  36.  
  37.     if (fDoc)
  38.         {
  39.         m_pDoc=(LPCPatronDoc)pObj;
  40.         m_pPage=NULL;
  41.         }
  42.     else
  43.         {
  44.         m_pDoc=NULL;
  45.         m_pPage=(LPPAGE)pObj;
  46.         }
  47.  
  48.     m_punkOuter=punkOuter;
  49.     return;
  50.     }
  51.  
  52. CImpIOleItemContainer::~CImpIOleItemContainer(void)
  53.     {
  54.     return;
  55.     }
  56.  
  57.  
  58.  
  59.  
  60. /*
  61.  * CImpIOleItemContainer::QueryInterface
  62.  * CImpIOleItemContainer::AddRef
  63.  * CImpIOleItemContainer::Release
  64.  *
  65.  * Purpose:
  66.  *  IUnknown members for CImpIOleItemContainer object.
  67.  */
  68.  
  69. STDMETHODIMP CImpIOleItemContainer::QueryInterface(REFIID riid, LPVOID FAR *ppv)
  70.     {
  71.     return m_punkOuter->QueryInterface(riid, ppv);
  72.     }
  73.  
  74.  
  75. STDMETHODIMP_(ULONG) CImpIOleItemContainer::AddRef(void)
  76.     {
  77.     ++m_cRef;
  78.     return m_punkOuter->AddRef();
  79.     }
  80.  
  81. STDMETHODIMP_(ULONG) CImpIOleItemContainer::Release(void)
  82.     {
  83.     --m_cRef;
  84.     return m_punkOuter->Release();
  85.     }
  86.  
  87.  
  88.  
  89. /*
  90.  * CImpIOleItemContainer::ParseDisplayName
  91.  *
  92.  * Purpose:
  93.  *  Inherited member of IParseDisplayName that takes a string name and
  94.  *  turns out a moniker for it.
  95.  *
  96.  * Parameters:
  97.  *  pbc             LPBC to the binding context
  98.  *  pszName         LPSTR to the name to parse.
  99.  *  pchEaten        ULONG FAR * into which to store how many characters
  100.  *                  we scanned in the display name.
  101.  *  ppmk            LPMONIKER FAR * in which to return the moniker.
  102.  *
  103.  * Return Value:
  104.  *  HRESULT         NOERROR if successful, error code otherwise.
  105.  */
  106.  
  107. STDMETHODIMP CImpIOleItemContainer::ParseDisplayName(LPBC pbc, LPSTR pszName
  108.     , ULONG FAR * pchEaten, LPMONIKER FAR *ppmk)
  109.     {
  110.     *ppmk=NULL;
  111.     return ResultFromScode(E_NOTIMPL);
  112.     }
  113.  
  114.  
  115.  
  116.  
  117. /*
  118.  * CImpIOleItemContainer::EnumObjects
  119.  *
  120.  * Purpose:
  121.  *  Creates and returns an IEnumUnknown object that allows the caller
  122.  *  to walk through the objects in this continer thing.
  123.  *
  124.  * Parameters:
  125.  *  dwFlags         DWORD specifying what kind of objects to
  126.  *                  enumerate.
  127.  *  ppEnum          LPENUMUNKNOWN FAR * into which to return the enumerator
  128.  *
  129.  * Return Value:
  130.  *  HRESULT         NOERROR if successful, error code otherwise.
  131.  */
  132.  
  133. STDMETHODIMP CImpIOleItemContainer::EnumObjects(DWORD dwFlags
  134.     , LPENUMUNKNOWN FAR *ppEnum)
  135.     {
  136.     *ppEnum=NULL;
  137.     return ResultFromScode(E_NOTIMPL);
  138.     }
  139.  
  140.  
  141.  
  142.  
  143. /*
  144.  * CImpIOleItemContainer::LockContainer
  145.  *
  146.  * Purpose:
  147.  *  Establishes a lock on the container to prevent it from shutting down
  148.  *  outside of user control.  This is used to control the lifetime of
  149.  *  the container when it's used to update a link to an embedded object
  150.  *  within it.  If we're unlock and the user has not taken control,
  151.  *  we close.
  152.  *
  153.  * Parameters:
  154.  *  fLock           BOOL indicating a lock or unlock.
  155.  *
  156.  * Return Value:
  157.  *  HRESULT         NOERROR if successful, error code otherwise.
  158.  */
  159.  
  160. STDMETHODIMP CImpIOleItemContainer::LockContainer(BOOL fLock)
  161.     {
  162.     /*
  163.      * This is pretty much the same implementation as
  164.      * IClassFactory::LockServer, and we can use the same lock
  165.      * count to accomplish our goal.
  166.      */
  167.  
  168.     if (fLock)
  169.         g_cLock++;
  170.     else
  171.         {
  172.         g_cLock--;
  173.  
  174.         /*
  175.          * To centralize shutdown, we'll artificially increase the object
  176.          * count here and call ObjectDestroyed, which will decrement the
  177.          * count, see that there are no objects or locks, then shut down.
  178.          */
  179.         g_cObj++;
  180.         ObjectDestroyed();
  181.         }
  182.  
  183.     return NOERROR;
  184.     }
  185.  
  186.  
  187.  
  188.  
  189.  
  190.  
  191. /*
  192.  * CImpIOleItemContainer::GetObject
  193.  *
  194.  * Purpose:
  195.  *  Returns the requested interface pointer on an object in this
  196.  *  container.
  197.  *
  198.  * Parameters:
  199.  *  pszItem         LPSTR to the item we must locate.
  200.  *  dwSpeed         DWORD identifying how long the caller is willing to wait.
  201.  *  pcb             LPBINDCTX providing the binding context.
  202.  *  riid            REFIID of the interface requested.
  203.  *  ppv             LPLPVOID into which to return the object.
  204.  *
  205.  * Return Value:
  206.  *  HRESULT         NOERROR if successful, error code otherwise.
  207.  */
  208.  
  209. STDMETHODIMP CImpIOleItemContainer::GetObject(LPSTR pszItem, DWORD dwSpeed
  210.     , LPBINDCTX pbc, REFIID riid, LPVOID FAR *ppv)
  211.     {
  212.     DWORD       dw;
  213.     char        szTemp[40];     //Local assumes SS==DS
  214.     HRESULT     hr=ResultFromScode(E_FAIL);
  215.     LPPAGE      pPage;
  216.     LPTENANT    pTenant;
  217.     LPUNKNOWN   pObj;
  218.     UINT        i, iCur;
  219.  
  220.     *ppv=NULL;
  221.  
  222.     if (m_fDoc)
  223.         {
  224.         /*
  225.          * The item name should be "Page n", so we'll do it the
  226.          * easy way:  call atol on pszItem+5 (we always know that
  227.          * we'll have "Page " there since we put it there (see
  228.          * CPage::GetStorageName).
  229.          */
  230.  
  231.         lstrcpy(szTemp, (LPSTR)(pszItem+5));
  232.         dw=atol(szTemp);
  233.  
  234.         i=m_pDoc->m_pPG->IPageGetFromID(dw, &pPage, FALSE);
  235.  
  236.         if (-1==i)
  237.             return hr;
  238.  
  239.         /*
  240.          * If we're asked for immediate speed, only do this if the
  241.          * page is already current, i.e. everything is loaded.
  242.          */
  243.         iCur=m_pDoc->m_pPG->CurPageGet();
  244.  
  245.         if (BINDSPEED_IMMEDIATE==dwSpeed && iCur!=i)
  246.             return ResultFromScode(MK_E_EXCEEDEDDEADLINE);
  247.  
  248.         m_pDoc->m_pPG->CurPageSet(i);
  249.  
  250.         //This will have changed to be the current page now.
  251.         if (NULL!=m_pDoc->m_pPG->m_pPageCur)
  252.             hr=m_pDoc->m_pPG->m_pPageCur->QueryInterface(riid, ppv);
  253.         }
  254.     else
  255.         {
  256.         if (FTenantFromName(pszItem, &pTenant))
  257.             {
  258.             pTenant->ObjectGet(&pObj);
  259.  
  260.             /*
  261.              * If we're asked for immediate or moderate, only work
  262.              * if the object is already running.
  263.              */
  264.             hr=IsRunning(pszItem);  //This is the function below
  265.  
  266.             if ((BINDSPEED_IMMEDIATE==dwSpeed
  267.                 || BINDSPEED_MODERATE==dwSpeed) && NOERROR!=hr)
  268.                 hr=ResultFromScode(MK_E_EXCEEDEDDEADLINE);
  269.             else
  270.                 {
  271.                 //IMPORTANT:  Make sure this object is running first
  272.                 OleRun(pObj);
  273.                 hr=pObj->QueryInterface(riid, ppv);
  274.                 }
  275.  
  276.             pObj->Release();
  277.             }
  278.         else
  279.             hr=ResultFromScode(MK_E_NOOBJECT);
  280.         }
  281.  
  282.     return hr;
  283.     }
  284.  
  285.  
  286.  
  287.  
  288.  
  289.  
  290. /*
  291.  * CImpIOleItemContainer::GetObjectStorage
  292.  *
  293.  * Purpose:
  294.  *  Similar to get Object in that we have to locate the object
  295.  *  described by a given name, but instead of returning any old
  296.  *  interface we return a storage element.
  297.  *
  298.  * Parameters:
  299.  *  pszItem         LPSTR to the item we must locate.
  300.  *  pcb             LPBINDCTX providing the binding context.
  301.  *  riid            REFIID of the interface requested.  Usually
  302.  *                  IStorage or IStream.
  303.  *  ppv             LPLPVOID into which to return the object.
  304.  *
  305.  * Return Value:
  306.  *  HRESULT         NOERROR if successful, error code otherwise.
  307.  */
  308.  
  309. STDMETHODIMP CImpIOleItemContainer::GetObjectStorage(LPSTR pszItem
  310.     , LPBINDCTX pbc, REFIID riid, LPVOID FAR *ppv)
  311.     {
  312.     LPTENANT    pTenant;
  313.  
  314.     *ppv=NULL;
  315.  
  316.     if (m_fDoc)
  317.